import { Asset, AssetManager, assetManager, error, log } from "cc";

//ab包 模块配置
interface IItem {
    assetType: any,
    url: string
}
export interface IPkg {
    abName: string,
    urls: Array<IItem>
}

export class ResManager {
    //总的ab包数
    private totalAb: number = 0;
    //当前加载到的第几个ab包
    private nowAb: number = 0;
    //加载的总资源数
    private total: number = 0;
    //当前加载的第几个资源 
    private now: number = 0;

    private abBunds: any = {};
    private progressFunc: Function|null = null;
    private endFunc: Function|null = null;


    private static _inst: ResManager;
    public static get inst(): ResManager {
        if (this._inst == null) {
            this._inst = new ResManager();
        }

        return this._inst;
    }

    private loadDirAssetsInAssetsBundle(resPkg: any,abBundle: any): void {
        // cc.log('loadDirAssetsInAssetsBundle = ',resPkg.abName);
        var urlSet = resPkg.urls;
        for (let i = 0; i < urlSet.length; i++) {
            const element = urlSet[i];
            let dirName = element.url;
            let typeClass = element.assetType;
            this.loadDirRes(abBundle, dirName, typeClass);
        }
    }

    private releaseDirAssetInAssetBundel(resPkg: any,abBundle: any){
        var urlSet = resPkg.urls;
        for (let i = 0; i < urlSet.length; i++) {
            const element = urlSet[i];
            let dirName = element.url;
            let typeClass = element.assetType;
            this.loadDirRes(abBundle, dirName, typeClass);
        }
    }

    private releaseDirRes(abBundle: AssetManager.Bundle, dirName: any, typeClasss: any){
        // abBundle.releaseAsset()
    }

     /**
     * 批量加载目录下的资源
     * @param abBundle 
     * @param dirName 
     * @param typeClasss 
     */
     private loadDirRes(abBundle: any, dirName: any, typeClasss: any): void {
        let self = this;
        // cc.log('====loadDirRes=====',this.now,this.total,abBundle,dirName,typeClasss);
        abBundle.loadDir(dirName, typeClasss, (error: any, asset: any)=>{
            self.now ++;
            // cc.log('====loadDirRes1=====',this.now,this.total);
            if (error) {
                log("loadDir Res " + dirName + " error: " + error);
            }
            else {
                // cc.log("loadDir Res " + dirName + " success!",asset);
            }

            if (self.progressFunc) {
                self.progressFunc(self.now, self.total);
            }

            if (self.now >= self.total) {   
                
                if (self.endFunc !== null) {
                    self.endFunc();
                }
            }
        })
    }

    private loadAssetsBundles(abName: string, endFunc: Function): void {
        // cc.log('========loadAssetsBundles===========',abName);
        if(!this.abBunds[abName]){
            // console.log('=============loadAssetsBundles=============',abName)
            assetManager.loadBundle(abName, (err, bundle)=>{
                if(err !== null) {
                    log("[ResMgr1]:Load AssetsBundle Error: " + abName);
                    this.abBunds[abName] = null;
                } 
                else {
                    this.abBunds[abName] = bundle;
                }
                if(endFunc) {
                    endFunc(bundle);
                }
            });
        }   
    }


    //=======================================================================================
    /**
   * 加载多个ab包配置
   * @param pkgs  数组
   */
    public loadDirAssetboundle(pkgs: Array<IPkg>, progressFunc: Function | null, endFunc: Function) {
        let self = this;
        this.total = 0;
        this.now = 0;
        this.totalAb = 0;
        this.nowAb = 0;
        this.progressFunc = progressFunc;
        this.endFunc = endFunc;

        for (let i = 0; i < pkgs.length; i++) {
            const pkg = pkgs[i];
            if (!this.abBunds[pkg.abName]) {
                this.totalAb++;
                this.total += pkg.urls.length;
            }
        }
        // cc.log('====loadDirAssetboundle=====', this.totalAb, this.total)
        if (this.totalAb == 0 || this.total == 0) {
            // cc.log('====loadDirAssetboundle=====')
            endFunc && endFunc()
            return
        }

        // cc.log('this.totalAb1 = ', this.totalAb, ' this.total1 =', this.total);
        pkgs.forEach(element => {
            let assets = element.urls;
            this.loadAssetsBundles(element.abName, (abBundle) => {
                self.nowAb++;
                this.loadDirAssetsInAssetsBundle(element, abBundle)
            });
        });
    }

    /**
    * 获取资源
    * @param abName  ab包名
    * @param resUrl  资源名（不带路径的） ,不带资源名， 如 aa.png ，不要 .png
    * @param type  资源类型 cc.Prefab | cc.SpriteFrame ...
    * @returns 
    */
    public getAsset(abName: string, resUrl: string, type: any): Asset {
        // cc.log('====getAsset===='+abName + resUrl + "  "+ type); 
        let res = null;
        var bondule: AssetManager.Bundle | null = assetManager.getBundle(abName);
        if (!bondule) {
            error("[error]: " + abName + " AssetsBundle not loaded !!!");
            return null;
        }
        return bondule.get(resUrl, type);
    }

    //释放资源
    public ReleaseAllAssetInBundle(bundleName: string): void {
        var bundle: AssetManager.Bundle = assetManager.getBundle(bundleName);
        if(bundle === null) {
            return;
        }
        // 释放所有属于 Asset Bundle 的资源
        //这里谨慎处理，移除bundle之前手动释放
        bundle.releaseAll();
        //移除bundle
        assetManager.removeBundle(bundle);
        delete this.abBunds[bundleName];
        // console.log('====ReleaseAllAssetInBundle=========',bundleName,bundle,this.abBunds)
    } 

    public ReleaseDirAssetboundle(){

    }
}